package cn.yyh.serviceOrder.service.impl;

import cn.yyh.commons.constant.JobTypes;
import cn.yyh.commons.exception.MyException;
import cn.yyh.commons.service.impl.MyBaseServiceImpl;
import cn.yyh.commons.utils.BusinessConstant;
import cn.yyh.commons.utils.CodeGenerateUtils;
import cn.yyh.commons.utils.PageInfo;
import cn.yyh.serviceOrder.client.*;
import cn.yyh.serviceOrder.domain.*;
import cn.yyh.serviceOrder.mapper.OrderAddressMapper;
import cn.yyh.serviceOrder.mapper.ProductOrderDetailMapper;
import cn.yyh.serviceOrder.mapper.ProductOrderMapper;
import cn.yyh.serviceOrder.quartz.sevice.IQuartzService;
import cn.yyh.serviceOrder.quartz.utils.QuartzJobInfo;
import cn.yyh.serviceOrder.query.ProductOrderQuery;
import cn.yyh.serviceOrder.service.IProductOrderService;
import cn.yyh.serviceOrder.utils.ConvertUtils;
import cn.yyh.serviceOrder.utils.JudgeUtil;
import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Service
public class ProductOrderServiceImpl extends MyBaseServiceImpl<ProductOrderMapper, ProductOrder> implements IProductOrderService {
    @Autowired
    private UserClient userClient;
    @Autowired
    private ProductClient productClient;
    @Autowired
    private ProductOrderDetailMapper detailMapper;
    @Autowired
    private UserAddressClient userAddressClient;
    @Autowired
    private OrderAddressMapper orderAddressMapper;
    @Autowired
    private PayBillClient payBillClient;
    @Autowired
    private IQuartzService quartzService;
    @Autowired
    private EmpClient empClient;


    @Override
    public String submit(Map<String, Object> map, Long id, String token) {

        // 1.数据校验
        Integer serviceMethod = Integer.valueOf(map.get("service_method").toString());
        Long addressId = Long.valueOf(map.get("address_id").toString());
        Long payMethod = Long.valueOf(map.get("pay_method").toString());
        Long productId = Long.valueOf(map.get("productId").toString());
        Long salecount = Long.valueOf(map.get("salecount").toString());

        JudgeUtil.isNull(serviceMethod,addressId,payMethod,productId,salecount);

        String client = userClient.getByLoginInfoId(id,token);
        User user = ConvertUtils.toUser(ConvertUtils.user(client));

        String byId = productClient.getById(productId, token);
        Product product = ConvertUtils.toProduct(ConvertUtils.product(byId));
        product.setSalecount(product.getSalecount()+salecount);
        productClient.saveOrUpdate(product,token);
        // 3.生成订单
        ProductOrder productOrder = initProductOrder(user, product,salecount);
        baseMapper.save(productOrder);

        ProductOrderDetail orderDetail = initProductDetailOrder(productOrder,product,salecount);
        detailMapper.save(orderDetail);

        // 4.生成对应的订单地址
        OrderAddress orderAddress = initOrderAddress(addressId, productOrder,token);
        orderAddressMapper.save(orderAddress);

        // 5.支付订单并支付
        PayBill payBill = initPayBill(payMethod, user, productOrder);
        String info = payBillClient.save(payBill, token);
        JSONObject jsonObject = JSONObject.parseObject(info).getJSONObject("data").getJSONObject("bill");
        payBill.setId(Long.valueOf(String.valueOf(jsonObject.get("id"))));


        // @TODO 6.超时未支付自动取消
        QuartzJobInfo jobInfo = new QuartzJobInfo();
        jobInfo.setJobName(JobTypes.PAY_OVER_TIME_PRODUCT_ORDER + productOrder.getId());
        Map<String, Object> m = new HashMap<>();
        m.put("type", JobTypes.PAY_OVER_TIME_PRODUCT_ORDER);
        m.put("orderId", productOrder.getId());
        jobInfo.setParams(m);
        jobInfo.setFireDate(productOrder.getLastPayTime());
        quartzService.addJob(jobInfo);

        return payBillClient.pay(payBill, token);
    }

    @Override
    public void deleteByQuartz(Long id2) {
        ProductOrder order = baseMapper.getById(id2);
        if (order.getState() == 0) {
            order.setState(-1);
            baseMapper.update(order);
            System.out.println("quartz 触发直接取消订单："+id2);
        }else if (order.getState() == 2) {
            order.setState(3);
            baseMapper.update(order);
            System.out.println("quartz 触发直接取消订单："+id2);
        }
    }

    @Override
    public PageInfo<ProductOrder> queryByAdmin(ProductOrderQuery query, Long id, String token) {
        String infoId = empClient.getByLoginInfoId(id, token);
        Employee employee = ConvertUtils.toEmp(ConvertUtils.emp(infoId));
        if (employee.getShopId() != null) {
            query.setShopId(employee.getShopId());
        }
        return super.pageQuery(query);
    }

    @Override
    public PageInfo<ProductOrder> queryByUser(ProductOrderQuery query, Long id,String token) {
        String client = userClient.getByLoginInfoId(id,token);
        User user = ConvertUtils.toUser(ConvertUtils.user(client));
        query.setUserId(user.getId());
        return super.pageQuery(query);
    }

    @Override
    public void successful(Long id) {
        ProductOrder byId = baseMapper.getById(id);
        byId.setState(2);
        byId.setLastConfirmTime(new Date(System.currentTimeMillis() + 1000 * 60));

        QuartzJobInfo jobInfo = new QuartzJobInfo();
        jobInfo.setJobName(JobTypes.CONFIRM_OVER_TIME_PRODUCT_ORDER + byId.getId());
        Map<String, Object> m = new HashMap<>();
        m.put("type", JobTypes.CONFIRM_OVER_TIME_PRODUCT_ORDER);
        m.put("orderId", byId.getId());
        jobInfo.setParams(m);
        jobInfo.setFireDate(byId.getLastConfirmTime());
        quartzService.addJob(jobInfo);

        baseMapper.update(byId);

    }

    @Override
    public void cancel(Long id,Long logininfoId,String token) {
        ProductOrder byId = baseMapper.getById(id);
        String client = userClient.getByLoginInfoId(logininfoId, token);
        JSONObject user = ConvertUtils.user(client);
        String infoId = empClient.getByLoginInfoId(logininfoId, token);
        JSONObject emp = ConvertUtils.emp(infoId);
        if (user != null && user.get("id") != null) {
            if (byId.getState() == 3 || byId.getState() == -1) {
                throw new MyException("订单已完成,无需取消");
            }
            byId.setState(-1);
        }
        if (emp != null && emp.get("id") != null) {
            if (byId.getState() == 1 ||
                    byId.getState() == 2 ||
                    byId.getState() == 3) {
                throw new MyException("用户已付款,不能取消,请与用户沟通");
            }
            byId.setState(-1);
        }

        baseMapper.update(byId);
    }

    @Override
    public void confirm(Long id) {
        ProductOrder byId = baseMapper.getById(id);
        if (byId.getState() == 2) {
            byId.setState(3);
        }
        baseMapper.update(byId);
        quartzService.removeJob(JobTypes.CONFIRM_OVER_TIME_PRODUCT_ORDER+byId.getId());
    }

    private PayBill initPayBill(Long payMethod, User user, ProductOrder productOrder) {
        PayBill payBill = new PayBill();
        payBill.setDigest(productOrder.getDigest());
        payBill.setMoney(productOrder.getPrice());
        payBill.setUnionPaySn(productOrder.getPaySn());
        payBill.setLastPayTime(new Date(System.currentTimeMillis() + 15*1000 * 60));
        payBill.setPayChannel(payMethod);
        payBill.setBusinessType(BusinessConstant.BUSINESS_TYPE_PRODUCT);
        payBill.setBusinessKey(productOrder.getId());
        payBill.setCreateTime(new Date());
        payBill.setUser_id(productOrder.getUser_id());
        payBill.setShop_id(productOrder.getShop_id());
        payBill.setNickName(user.getUsername());
        return payBill;
    }

    private OrderAddress initOrderAddress(Long addressId, ProductOrder productOrder,String token) {
        String byId = userAddressClient.getById(addressId, token);
        UserAddress userAddress = ConvertUtils.toUserAddress(ConvertUtils.userAddress(byId));
        OrderAddress orderAddress = new OrderAddress();
        BeanUtils.copyProperties(userAddress,orderAddress);
        orderAddress.setCreateTime(new Date());
        orderAddress.setUpdateTime(new Date());
        orderAddress.setOrder_id(productOrder.getId());
        orderAddress.setOrderSn(productOrder.getOrderSn());
        return orderAddress;
    }

    private ProductOrderDetail initProductDetailOrder(ProductOrder order,Product product,Long count) {
        ProductOrderDetail orderDetail = new ProductOrderDetail();
        orderDetail.setName(product.getName());
        orderDetail.setResources(product.getResources());
        orderDetail.setSaleprice(product.getSaleprice());
        orderDetail.setCostprice(new BigDecimal(product.getCostprice()));
        orderDetail.setCreatetime(new Date());
        orderDetail.setSalecount(count);
        orderDetail.setOrder_id(order.getId());
        orderDetail.setProduct_id(product.getId());
        return orderDetail;
    }

    private ProductOrder initProductOrder(User user, Product product,Long salecount) {
        ProductOrder productOrder = new ProductOrder();
        BigDecimal count = new BigDecimal(salecount);
        productOrder.setDigest("[摘要]对{"+ product.getName()+"}的服务订单！");
        productOrder.setPrice((product.getSaleprice().multiply(count).add(new BigDecimal(10))));
        String orderSn = CodeGenerateUtils.generateOrderSn(user.getId());
        productOrder.setPaySn(CodeGenerateUtils.generateUnionPaySn());
        productOrder.setOrderSn(orderSn);
        productOrder.setLastPayTime(new Date(System.currentTimeMillis()+1000*60*15));
        productOrder.setProduct_id(product.getId());
        productOrder.setUser_id(user.getId());
        productOrder.setShop_id(product.getShopId());
        return productOrder;
    }
}
